<page-header title="'Stack details'" breadcrumbs="[{label:'Stacks', link:'docker.stacks'}, stackName]" reload="true"> </page-header>

<div class="row">
  <div class="col-sm-12">
    <rd-widget>
      <rd-widget-body>
        <uib-tabset active="state.activeTab">
          <!-- tab-info -->
          <uib-tab index="0">
            <uib-tab-heading>
              <pr-icon icon="'list'"></pr-icon>
              Stack
            </uib-tab-heading>
            <div style="margin-top: 10px">
              <!-- stack-information -->
              <div ng-if="external || orphaned">
                <div class="col-sm-12 form-section-title"> Information </div>
                <div class="form-group">
                  <span class="small">
                    <p class="text-muted">
                      <pr-icon icon="'alert-triangle'" mode="'warning'" class-name="'mr-0.5'"></pr-icon>
                      <span ng-if="external">This stack was created outside of Portainer. Control over this stack is limited.</span>
                      <span ng-if="orphaned">This stack is orphaned. You can re-associate it with the current environment using the "Associate to this environment" feature.</span>
                    </p>
                  </span>
                </div>
              </div>
              <!-- !stack-information -->
              <!-- stack-details -->
              <div>
                <div class="col-sm-12 form-section-title"> Stack details </div>
                <div class="form-group">
                  {{ stackName }}

                  <button
                    authorization="PortainerStackUpdate"
                    ng-if="regular && stack.Status === 2"
                    ng-disabled="state.actionInProgress"
                    class="btn btn-xs btn-success"
                    ng-click="startStack()"
                  >
                    <pr-icon icon="'play'"></pr-icon>
                    Start this stack
                  </button>

                  <button
                    ng-if="regular && stack.Status === 1"
                    authorization="PortainerStackUpdate"
                    ng-disabled="state.actionInProgress"
                    class="btn btn-xs btn-light"
                    ng-click="stopStack()"
                  >
                    <pr-icon icon="'stop-circle'"></pr-icon>
                    Stop this stack
                  </button>

                  <button authorization="PortainerStackDelete" class="btn btn-xs btn-light" ng-click="removeStack()" ng-if="!external || stack.Type == 1">
                    <pr-icon icon="'trash-2'"></pr-icon>
                    Delete this stack
                  </button>

                  <button
                    ng-if="regular && stackFileContent"
                    class="btn btn-primary btn-xs"
                    ui-sref="docker.templates.custom.new({fileContent: stackFileContent, type: stack.Type})"
                  >
                    <pr-icon icon="'plus'"></pr-icon>
                    Create template from stack
                  </button>
                  <button
                    authorization="PortainerStackUpdate"
                    ng-if="regular && stackFileContent && !stack.FromAppTemplate && stack.GitConfig"
                    ng-disabled="state.actionInProgress"
                    ng-click="detachStackFromGit()"
                    button-spinner="state.actionInProgress"
                    class="btn btn-primary btn-xs"
                  >
                    <pr-icon icon="'arrow-right'" class-name="'mr-1'"></pr-icon>
                    <span ng-hide="state.actionInProgress">Detach from Git</span>
                    <span ng-show="state.actionInProgress">Detachment in progress...</span>
                  </button>
                </div>
              </div>
              <!-- !stack-details -->

              <!-- associate -->
              <div ng-if="orphaned">
                <div class="col-sm-12 form-section-title"> Associate to this environment </div>
                <p class="small text-muted"> This feature allows you to re-associate this stack to the current environment. </p>
                <form class="form-horizontal">
                  <por-access-control-form form-data="formValues.AccessControlData" hide-title="true"></por-access-control-form>
                  <div class="form-group">
                    <div class="col-sm-12">
                      <button
                        type="button"
                        class="btn btn-primary btn-sm"
                        ng-disabled="state.actionInProgress"
                        ng-click="associateStack()"
                        button-spinner="state.actionInProgress"
                        style="margin-left: -5px"
                      >
                        <pr-icon icon="'refresh-cw'" class="!mr-1"></pr-icon>
                        <span ng-hide="state.actionInProgress">Associate</span>
                        <span ng-show="state.actionInProgress">Association in progress...</span>
                      </button>
                      <span class="text-danger" ng-if="state.formValidationError" style="margin-left: 5px">{{ state.formValidationError }}</span>
                    </div>
                  </div>
                </form>
              </div>
              <!-- !associate -->

              <div ng-if="!orphaned">
                <stack-redeploy-git-form
                  ng-if="stack.GitConfig && !stack.FromAppTemplate && !state.actionInProgress"
                  model="stack.GitConfig"
                  stack="stack"
                  authorization="PortainerStackUpdate"
                  endpoint="applicationState.endpoint"
                >
                </stack-redeploy-git-form>
                <stack-duplication-form
                  ng-if="regular && endpoints.length > 0"
                  endpoints="endpoints"
                  groups="groups"
                  current-endpoint-id="endpoint.Id"
                  on-duplicate="duplicateStack(name, endpointId)"
                  on-migrate="migrateStack(name, endpointId)"
                  yaml-error="state.yamlError"
                >
                </stack-duplication-form>
              </div>
            </div>
          </uib-tab>
          <!-- !tab-info -->
          <!-- tab-file -->
          <uib-tab index="1" select="showEditor()" ng-if="!external && (!stack.GitConfig || stack.FromAppTemplate)">
            <uib-tab-heading>
              <pr-icon icon="'edit-2'" class-name="'mr-1'"></pr-icon>
              Editor
            </uib-tab-heading>
            <form class="form-horizontal" ng-if="state.showEditorTab" style="margin-top: 10px" name="stackUpdateForm">
              <div class="form-group">
                <span class="col-sm-12 text-muted small" style="margin-bottom: 7px" ng-if="stackType == STACK_TYPES.DockerCompose && composeSyntaxMaxVersion == 2">
                  This stack will be deployed using the equivalent of <code>docker compose</code>. Only Compose file format version <b>2</b> is supported at the moment.
                </span>
                <span class="col-sm-12 text-muted small" style="margin-bottom: 7px" ng-if="stackType == STACK_TYPES.DockerCompose && composeSyntaxMaxVersion > 2">
                  This stack will be deployed using <code>docker compose</code>.
                </span>
                <span class="col-sm-12 text-muted small">
                  You can get more information about Compose file format in the <a href="https://docs.docker.com/compose/compose-file/" target="_blank">official documentation</a>.
                </span>
                <div class="col-sm-12" ng-if="state.yamlError">
                  <span class="text-danger small">{{ state.yamlError }}</span>
                </div>
              </div>
              <div class="form-group">
                <div class="col-sm-12">
                  <code-editor
                    read-only="orphaned"
                    identifier="stack-editor"
                    placeholder="Define or paste the content of your docker compose file here"
                    yml="true"
                    on-change="(editorUpdate)"
                    value="stackFileContent"
                  ></code-editor>
                </div>
              </div>

              <!-- environment-variables -->
              <div ng-if="stack">
                <stack-environment-variables-panel
                  values="formValues.Env"
                  on-change="(handleEnvVarChange)"
                  show-help-message="true"
                  is-foldable="true"
                ></stack-environment-variables-panel>
              </div>
              <!-- !environment-variables -->

              <!-- webhook -->
              <div ng-if="isAdmin && applicationState.endpoint.type !== 4">
                <div class="form-section-title"> Webhooks</div>
                <por-switch-field
                  name="EnableWebhook"
                  checked="formValues.EnableWebhook"
                  label-class="'col-sm-2'"
                  tooltip="'Create a webhook (or callback URI) to automate the update of this stack. Sending a POST request to this callback URI (without requiring any authentication) will pull the most up-to-date version of the associated image and re-deploy this stack.'"
                  label="'Create a Stack webhook'"
                  feature-id="'stack-webhook'"
                ></por-switch-field>
              </div>
              <!-- !webhook -->

              <!-- options -->
              <div ng-if="stack.Type === 1 && applicationState.endpoint.apiVersion >= 1.27" authorization="PortainerStackUpdate">
                <div class="col-sm-12 form-section-title"> Options </div>
                <div class="form-group">
                  <div class="col-sm-12">
                    <por-switch-field
                      name="prune"
                      checked="formValues.Prune"
                      tooltip="'Prune services that are no longer referenced.'"
                      label-class="'col-sm-2'"
                      label="'Prune services'"
                      on-change="(onPruneChange)"
                    ></por-switch-field>
                  </div>
                </div>
              </div>
              <!-- !options -->
              <div authorization="PortainerStackUpdate">
                <div class="col-sm-12 form-section-title"> Actions </div>
                <div class="form-group">
                  <div class="col-sm-12">
                    <button
                      type="button"
                      class="btn btn-sm btn-primary"
                      ng-disabled="state.actionInProgress || state.yamlError || !stackUpdateForm.$valid || !stackFileContent || orphaned"
                      ng-click="deployStack()"
                      button-spinner="state.actionInProgress"
                    >
                      <span ng-hide="state.actionInProgress">Update the stack</span>
                      <span ng-show="state.actionInProgress">Deployment in progress...</span>
                    </button>
                  </div>
                </div>
              </div>
            </form>
          </uib-tab>
          <!-- !tab-file -->
        </uib-tabset>
      </rd-widget-body>
    </rd-widget>
  </div>
</div>

<stack-containers-datatable
  ng-if="stackType !== STACK_TYPES.DockerSwarm && (!orphaned || orphanedRunning)"
  stack-name="stackName"
  environment="endpoint"
></stack-containers-datatable>

<docker-services-datatable ng-if="services && (!orphaned || orphanedRunning)" dataset="services" title-icon="list" on-refresh="(getServices)"></docker-services-datatable>

<!-- access-control-panel -->
<access-control-panel
  ng-if="stack && !orphaned"
  resource-id="stack.EndpointId + '_' + stack.Name"
  resource-control="stack.ResourceControl"
  resource-type="resourceType"
  environment-id="stack.EndpointId"
  on-update-success="(onUpdateResourceControlSuccess)"
>
</access-control-panel>
<!-- !access-control-panel -->
